<?php

    /**
     * Image
     *
     * Image handler library
     *
     * @package      Core
     * 
     * @license      Open Software License (OSL 3.0) see LICENCE-OSL file or http://opensource.org/licenses/osl-3.0.php
     */
    class Core_Image
    {

    ////////////////////////////////////////////////////////////////////////////
    //                                Variables                               //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * @var string
         */
        protected $_adapter;

        /**
         * @var string
         */
        protected $_fileName;

    ////////////////////////////////////////////////////////////////////////////
    //                                 Methods                                //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * Constructor
         *
         * @param       Core_Image_Adapter      $adapter : default value is GD2
         * @param       string                  $fileName
         * @return      void
         */
        public function __construct($fileName = null, $adapter = Core_Image_Adapter::ADAPTER_GD2)
        {
            $this->_getAdapter($adapter);
            $this->_fileName = $fileName;

            if (isset($fileName)) {
                $this->open();
            }
        }

        /**
         * Opens an image and creates image handle
         *
         * @throws      Core_Exception
         * @return      void
         */
        public function open()
        {
            $this->_getAdapter()->checkDependencies();

            if (!Core_IO_File::exists($this->_fileName)) {
                throw new Core_Exception("File '". $this->_fileName ."' doesn't exist");
            }

            $this->_getAdapter()->open($this->_fileName);
        }

        /**
         * Display handled image in your browser
         *
         * @return      void
         */
        public function display()
        {
            $this->_getAdapter()->display();
        }

        /**
         * Save handled image into file
         *
         * @param       string      $destination : default value is null
         * @param       string      $newFileName : default value is null
         * @return      void
         */
        public function save($destination = null, $newFileName = null)
        {
            $this->_getAdapter()->save($destination, $newFileName);
        }

        /**
         * Rotate an image
         *
         * @param       integer     $angle
         * @return      void
         */
        public function rotate($angle)
        {
            $this->_getAdapter()->rotate($angle);
        }

        /**
         * Crop an image
         *
         * @param       integer     $top : default value is 0
         * @param       integer     $left : default value is 0
         * @param       integer     $right : default value is 0
         * @param       integer     $bottom : default value is 0
         * @return      void
         */
        public function crop($top = 0, $left = 0, $right = 0, $bottom = 0)
        {
            $this->_getAdapter()->crop($left, $top, $right, $bottom);
        }

        /**
         * Resize an image
         *
         * @param       integer     $width
         * @param       integer     $height
         * @return      void
         */
        public function resize($width, $height = null)
        {
            $this->_getAdapter()->resize($width, $height);
        }

        /**
         * keepAspectRatio
         *
         * @param       boolean     $value
         * @return      void
         */
        public function keepAspectRatio($value)
        {
            return $this->_getAdapter()->keepAspectRatio($value);
        }

        /**
         * keepFrame
         *
         * @param       boolean     $value
         * @return      void
         */
        public function keepFrame($value)
        {
            return $this->_getAdapter()->keepFrame($value);
        }

        /**
         * keepTransparency
         *
         * @param       boolean     $value
         * @return      void
         */
        public function keepTransparency($value)
        {
            return $this->_getAdapter()->keepTransparency($value);
        }

        /**
         * constrainOnly
         *
         * @param       boolean     $value
         * @return      void
         */
        public function constrainOnly($value)
        {
            return $this->_getAdapter()->constrainOnly($value);
        }

        /**
         * backgroundColor
         *
         * @param       array       $value
         * @return      void
         */
        public function backgroundColor($value)
        {
            return $this->_getAdapter()->backgroundColor($value);
        }

        /**
         * Adds watermark to our image
         *
         * @param       string      $watermarkImage : absolute path to watermark image
         * @param       integer     $positionX : watermark X position
         * @param       integer     $positionY : watermark Y position
         * @param       integer     $watermarkImageOpacity : watermark image opacity
         * @param       boolean     $repeat : enable or disable watermark brick
         * @throws      Core_Exception
         * @return      void
         */
        public function watermark($watermarkImage, $positionX = 0, $positionY = 0, $watermarkImageOpacity = 30, $repeat = false)
        {
            if (!Core_IO_File::exists($watermarkImage)) {
                throw new Core_Exception("Required file '". $watermarkImage ."' doesn't exist");
            }

            $this->_getAdapter()->watermark($watermarkImage, $positionX, $positionY, $watermarkImageOpacity, $repeat);
        }

        /**
         * Get mime type of handled image
         *
         * @return      string
         */
        public function getMimeType()
        {
            return $this->_getAdapter()->getMimeType();
        }

        /**
         * Process
         *
         * @return      void
         */
        public function process()
        {
        }

        /**
         * Instruction
         *
         * @return      void
         */
        public function instruction()
        {
        }

        /**
         * Set image background color
         *
         * @param       integer     $color
         * @return      void
         */
        public function setImageBackgroundColor($color)
        {
            $this->_getAdapter()->imageBackgroundColor = intval($color);
        }

        /**
         * setWatermarkPosition
         *
         * @param       integer         $position
         * @return      Core_Image
         */
        public function setWatermarkPosition($position)
        {
            $this->_getAdapter()->setWatermarkPosition($position);
            return $this;
        }

        /**
         * setWatermarkWidth
         *
         * @param       integer         $width
         * @return      Core_Image
         */
        public function setWatermarkWidth($width)
        {
            $this->_getAdapter()->setWatermarkWidth($width);
            return $this;
        }

        /**
         * setWatermarkHeigth
         *
         * @param       integer         $height
         * @return      Core_Image
         */
        public function setWatermarkHeigth($heigth)
        {
            $this->_getAdapter()->setWatermarkHeigth($heigth);
            return $this;
        }

    ////////////////////////////////////////////////////////////////////////////
    //                            Protected Methods                           //
    ////////////////////////////////////////////////////////////////////////////

        /**
         * _getAdapter
         *
         * @param       string      $adapter
         * @return      Core_Image_Adapter_Abstract
         */
        protected function _getAdapter($adapter = null)
        {
            if (!isset($this->_adapter)) {
                $this->_adapter = Core_Image_Adapter::factory($adapter);
            }

            return $this->_adapter;
        }
    }
